<?php
// +----------------------------------------------------------------------
// | Description: 审批
// +----------------------------------------------------------------------
// | Author:  Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\oa\model;

use app\crm\model\Accounting;
use app\crm\model\Contract;
use app\crm\model\Receivables;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
use app\admin\model\Field;

class Examine extends Common
{
    /**
     * 为了数据库的整洁，同时又不影响Model和Controller的名称
     * 我们约定每个模块的数据表都加上相同的前缀，比如CRM模块用crm作为数据表前缀
     */
    protected $name = 'oa_examine';
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $autoWriteTimestamp = true;
    private $statusArr = ['0'=>'待审核','1'=>'审核中','2'=>'审核通过','3'=>'已拒绝','4'=>'已撤回'];

    /**
     * [getDataList 审批list]
     * @author Michael_xu
     * @param     [string]                   $map [查询条件]
     * @param     [number]                   $page     [当前页数]
     * @param     [number]                   $limit    [每页数量]
     * @return 
     */     
    public function getDataList($request)
    {   
        try {
            $userModel = new \app\admin\model\User();
            $fileModel = new \app\admin\model\File();
            $businessModel = new \app\crm\model\Business();
            $contactsModel = new \app\crm\model\Contacts();
            $contractModel = new \app\crm\model\Contract();
            $customerModel = new \app\crm\model\Customer();     
    
            $by = $request['by'] ? : 'my'; //my我发起的,examine我审批的,all全部(下属发起的)
            $user_id = $request['user_id'];
            $check_status = $request['check_status'];
            $order_sn=$request['order_sn'];//财务编号
            $customer_name=$request['customer_name'];//客户名称
            $order_type=$request['order_type'];//审批类型、退款申请、报销申请、开票申请、成本变更
            unset($request['order_type']);
            unset($request['customer_name']);
            unset($request['order_sn']);
            unset($request['by']);
            unset($request['user_id']);
            unset($request['check_status']);
            $request = $this->fmtRequest( $request );
            $map = $request['map'] ? : [];
            if (isset($map['search']) && $map['search']) {
                //普通筛选
                $map['examine.content'] = ['like', '%'.$map['search'].'%'];
            } else {
                $map = where_arr($map, 'oa', 'examine', 'index'); //高级筛选
            }
            unset($map['search']);
            //审批类型
            if (!$map['examine.category_id']) {
                $map['examine.category_id'] = array('gt',0); //审批类型
            }
            $map_str = '';
            $whereflow = '';
            switch ($by) {
                case 'my' : $map['examine.create_user_id'] = $user_id; break;
                case 'examine' : 
                    $map_str = "(( `check_user_id` LIKE '%,".$user_id.",%' OR `check_user_id` = ".$user_id." ) OR ( `flow_user_id` LIKE '%,".$user_id.",%'  OR `flow_user_id` = ".$user_id." ) )";
                    break;
                case 'already_examine' : 
                    //判断--工单库 管家只显示未捡取和自己捡取的数据 start 管家看到所有
                    $butler_group = db('admin_access')->where(['user_id' => $user_id, "group_id" => "32"])->find();
                    if($butler_group) {
                        // 获取所有的管家user_id
                        $userIds = db('admin_access')->where(["group_id" => "32"])->column('user_id');
                        $useridsWhere = [];
                        foreach ($userIds as $idk => $idv) {
                            $useridsWhere[] = " flow_user_id like '%".$idv."%' ";
                        }
                        $whereflow = implode(' or ',$useridsWhere);
                        // $map['flow_user_id'] = [['eq',$user_id],'or']; 
                    } else {
                        $map['flow_user_id'] = [['like','%,'.$user_id.',%'],['eq',$user_id],'or']; 
                    }
                    break; //已审
                case 'stay_examine' : 
                    $butler_group = db('admin_access')->where(['user_id' => $user_id, "group_id" => "32"])->find();
                    if($butler_group) {
                        // 获取所有的管家user_id
                        $userIds = db('admin_access')->where(["group_id" => "32"])->column('user_id');
                        $useridsWhere = [];
                        foreach ($userIds as $idk => $idv) {
                            $useridsWhere[] = " check_user_id like '%".$idv."%' ";
                        }
                        $whereflow = implode(' or ',$useridsWhere);
                        // $map['check_user_id'] = [['like','%,'.$user_id.',%'],['eq',$user_id],'or']; 
                    } else {
                        $map['check_user_id'] = [['like','%,'.$user_id.',%'],['eq',$user_id],'or'];  
                    }
                    break; //待审
                case 'all' : $auth_user_ids = getSubUserId(); $map['examine.create_user_id'] = array('in',$auth_user_ids); break; //全部
                default : $map['examine.create_user_id'] = $user_id; break;
            }
            $order = 'examine.update_time desc,examine.create_time asc';
            //发起时间
            if ($map['examine.between_time'][0] && $map['examine.between_time'][1]) {
                $start_time = $map['examine.between_time'][0];
                $end_time = $map['examine.between_time'][1];
                $map['examine.create_time'] = array('between',array($start_time,$end_time));
            }
            unset($map['examine.between_time']);
            //审核状态
            if ($check_status == 'all') {
                $map['examine.check_status'] = ['egt',0];
            } else {
                $map['examine.check_status'] = $check_status;
            }
            //根据客户名称进行搜索
            if($customer_name){
                //先获取客户customer_id
                $customerIdArr=Db::name("crm_customer")->where(["name"=>["like","%{$customer_name}%"]])->column("customer_id");
                if($customerIdArr){
                   $contractIdArr=Db::name("crm_contract")->where(["customer_id"=>["in",$customerIdArr]])->column("contract_id");
                   if($contractIdArr){
                       $examineIdArr=[];
                       foreach ($contractIdArr as $contract_id){
                           $relationExamineIdArr=Db::name("oa_examine_relation")->where(["contract_ids"=>["like","%,{$contract_id},%"]])->column("examine_id");
                           $examineIdArr=array_merge($examineIdArr,$relationExamineIdArr);
                       }
                       if($examineIdArr){
                           $map["examine.examine_id"]=array_unique($examineIdArr);
                       }
                   }
                }
            }
            //根绝财务编号进行搜索
            if($order_sn){
                //退款、报销、成本变更
                $financeExamineId=Db::name("crm_finance")->where(["receivables_code"=>["like","%{$order_sn}%"],"check_status"=>2,"order_type"=>["in",array("退款","报销","成本变更")]])->column("relation_id");
                //开票
                $invoiceExamineId=Db::name("crm_invoice")->where(["order_sn_all"=>["like","%{$order_sn}%"]])->column("examine_id");
                $order_sn_arr=array_unique(array_merge($financeExamineId,$invoiceExamineId));
                if($map["examine.examine_id"]){
                    $order_sn_arr=array_intersect($order_sn_arr,$map["examine.examine_id"]);
                }
                $map["examine.examine_id"]=$order_sn_arr;
            }
            //审批类型检索、退款申请、报销申请、开票申请、成本变更
            if($order_type){
                $orderTypeArr=[];
                switch ($order_type){
                    case "退款申请":
                        $orderTypeArr=Db::name("crm_finance")->where(["order_type"=>"退款"])->column("relation_id");
                        break;
                    case "报销申请":
                        $orderTypeArr=Db::name("crm_finance")->where(["order_type"=>"报销"])->column("relation_id");
                        break;
                    case "开票申请":
                        $orderTypeArr=Db::name("crm_invoice")->column("examine_id");
                        break;
                    case "成本变更":
                        $orderTypeArr=Db::name("crm_finance")->where(["order_type"=>"成本变更"])->column("relation_id");
                        break;
                    default:
                }
                if($orderTypeArr){
                    if($map["examine.examine_id"]){
                        $orderTypeArr=array_intersect($orderTypeArr,$map["examine.examine_id"]);
                    }
                    $map["examine.examine_id"]=array("in",$orderTypeArr);
                }
            }
            if($map["examine.examine_id"]){
                $map["examine.examine_id"]=["in",$map["examine.examine_id"][1]];
            }else{
                unset($map["examine.examine_id"]);
            }
            //2024-1-19 新增 待审核判断 start
            if($by=="stay_examine"){
                $map['examine.check_status'] = ['<>',3];
            }
            //2024-1-19 新增 待审核判断 end
            $join = [
                ['__ADMIN_USER__ user', 'user.id = examine.create_user_id', 'LEFT'],
                ['__OA_EXAMINE_CATEGORY__ examine_category', 'examine_category.category_id = examine.category_id', 'LEFT'],
            ];
            $list_view = db('oa_examine')
                         ->alias('examine')
                         ->where($map_str)
                         ->where($map)
                         ->where($whereflow)
                         ->join($join);
    
            $list = $list_view
                    ->page($request['page'], $request['limit'])
                    ->field('examine.*,user.realname,user.thumb_img,examine_category.title as category_name')
                    ->order($order)
                    ->select();
            $admin_user_ids = $userModel->getAdminId();
            foreach ($list as $k=>$v) {
                $list[$k]['create_user_info'] = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
                $causeCount = 0;
                $causeTitle = '';
                $duration = $v['duration'] ? : '0.0';
                $money = $v['money'] ? : '0.00';
                if (in_array($v['category_id'],['3','5'])) {
                    $causeCount = db('oa_examine_travel')->where(['examine_id' => $v['examine_id']])->count() ? : 0;
                    if ($v['category_id'] == 3) $causeTitle = $causeCount.'个行程,共'.$duration.'天';
                    if ($v['category_id'] == 5) $causeTitle = $causeCount.'个报销事项,共'.$money.'元';
                }
                $list[$k]['causeTitle'] = $causeTitle;
                $list[$k]['causeCount'] = $causeCount ? : 0;
                //关联业务
                $relation = [];
                $relation = db('oa_examine_relation')->where(['examine_id' => $v['examine_id']])->find();
                $list[$k]['businessList'] = $relation['business_ids'] ? $businessModel->getDataByStr($relation['business_ids']) : []; //商机
                $list[$k]['contactsList'] = $relation['contacts_ids'] ? $contactsModel->getDataByStr($relation['contacts_ids']) : []; //联系人
                $list[$k]['contractList'] = $relation['contract_ids'] ? $contractModel->getDataByStr($relation['contract_ids']) : []; //合同
                $list[$k]['customerList'] = $relation['customer_ids'] ? $customerModel->getDataByStr($relation['customer_ids']) : []; //客户
    
                //附件
                $fileList = [];
                $imgList = [];
                $where = [];
                $where['module'] = 'oa_examine';
                $where['module_id'] = $v['examine_id'];         
                $newFileList = [];
                $newFileList = $fileModel->getDataList($where);
                foreach ($newFileList['list'] as $val) {
                    if ($val['types'] == 'file') {
                        $fileList[] = $val;
                    } else {
                        $imgList[] = $val;
                    }
                }
                $list[$k]['fileList'] = $fileList ? : [];
                $list[$k]['imgList'] = $imgList ? : [];
    
                //创建人或管理员有撤销权限
                $permission = [];
                $is_recheck = 0;
                $is_update = 0;
                $is_delete = 0;
                //创建人或负责人或管理员有撤销权限
                if ($v['create_user_id'] == $user_id || in_array($user_id, $admin_user_ids)) {
                    if (!in_array($v['check_status'],['2','3','4'])) {
                        $is_recheck = 1;
                    }
                }
                //创建人（失败、撤销状态时可编辑）
                if ($v['create_user_id'] == $user_id && in_array($v['check_status'],['3','4'])) {
                    $is_update = 1;
                    $is_delete = 1;
                }
                $permission['is_recheck'] = $is_recheck;            
                $permission['is_update'] = $is_update;
                $permission['is_delete'] = $is_delete;
                $list[$k]['permission'] = $permission;
                $list[$k]['check_status_info'] = $this->statusArr[$v['check_status']];          
            }
            $dataCount = $this->alias('examine')
                         ->where($map_str)
                         ->where($map)
                         ->where($whereflow)
                         ->join($join)
                         ->count('examine_id');  
            $data = [];
            $data['list'] = $list;
            $data['dataCount'] = $dataCount ? : 0;
            return $data;
        } catch (\Exception $e) {
            var_dump($e->getMessage().$e->getLine());exit;
        }
    }

    /**
     * 创建审批信息
     * @author Michael_xu
     * @param  
     * @return                            
     */ 
    public function createData($param)
    {
        $fieldModel = new \app\admin\model\Field();
        $userModel = new \app\admin\model\User();
        $examineCategoryModel = new \app\oa\model\ExamineCategory();
        $examineDataModel = new \app\oa\model\ExamineData();
        if (!$param['category_id']) {
            $this->error = '参数错误';
            return false;
        }
        //2023-10-26 lina 修改 start
        //退款申请判断是否满足金额，回款金额不足不能退款
        if($param['category_id']==12 || $param['category_id']==30){
            if($param["money"] <= 0 && $param["recover_money"]<=0){
                $this->error = "退款金额和追会成本不能同时为0元";
                return false;
            }
            $receivables=Receivables::where(["receivables_id"=>$param["receivables_id"],"check_status"=>2])->find();
            if(empty($receivables)){
                $this->error = '该回款记录不存在或者未审核通过！';
                return false;
            }
            $recoverMoney=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->sum("recover_money");//已经追回的成本
            $refundMoney=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->sum("refund_money");//已退款和正在等待审核的退款金额
            $expenseMoneySum=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额
            $expenseMoney=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>2])->sum("reimburse_money");//已报销金额
            $max_recover_money=bcsub($expenseMoney,$recoverMoney,2);//最大可追回的报销金额
            $max_refund_money=bcsub($receivables["money"],bcadd($refundMoney,$expenseMoneySum),2);//最大该回款单可退款金额
            if($param["money"] < $param["calculate"]){
                $this->error = "退回业绩不能大于退款金额！";
                return false;
            }
            if($param["recover_money"] > $max_recover_money){
                $this->error = "追回金额不能超过{$max_recover_money}元！";
                return false;
            }
            if($param["calculate"] > $param["money"]){
                $this->error = "业绩处理金额不能超过{$param["money"]}元！";
                return false;
            }
            if($param["money"] > $max_refund_money){
                $this->error = "退款金额不能超过{$max_refund_money}元！";
                return false;
            }


            // 最大可调增成本  = 累计业绩
            // 变更的成本
            $change_crm_oeseng = db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"成本变更","check_status"=>["in",[0,1,2]]])->sum("crm_oeseng");
            // 退回业绩
            $calculate=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$receivables['number'],"check_status"=>["in",[0,1,2]]])->sum("calculate");
            // 回款单业绩
            $refund_calculate = bcsub($receivables["money"],$receivables["crm_oeseng"],2);
            // 最大可调增成本 = 业绩金额
            // 业绩=现有金额（回款单核算业绩+成本调整增减业绩）-退回业绩（退款申请）
            $performance = bcsub($refund_calculate,$change_crm_oeseng,2);
            //最大该回款单可退回业绩
            $max_refund_performance= bcadd($performance,$calculate,2);
            // // 退回业绩判断
            // $return_money = db("crm_finance")->where(["order_sn"=>$receivables["number"],"order_type"=>"回款","check_status"=>["in",[0,1,2]]])->find();
            // $return_calculate=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->sum("calculate");
            // $max_refund_performance = bcadd($return_money['calculate'],$return_calculate,2);
            if($param['calculate'] > $max_refund_performance) {
                $err_calculate = $max_refund_performance < 0 ? 0 : $max_refund_performance;
                $this->error = "退回业绩不能超过{$err_calculate}元！";
                return false;
            }

            $param["money"]=bcadd($param["money"],$param["recover_money"],2);//合并退款金额=退款金额+追回金额
        }
        //开票判断
        if ($param["category_id"]==14){
            //开票
            $contractModel = new Contract();
            $contract=$contractModel->find($param["contract_ids"][0]);
            $receivablesModel = new \app\crm\model\Receivables();
            //待已开票金额
            $money=$this->alias('examine')
                ->join('__OA_EXAMINE_RELATION__ examine_relation', 'examine_relation.examine_id = examine.examine_id', 'LEFT')
                ->where("examine_relation.contract_ids like '%,".$contract["contract_id"].",%'")
                ->where(["examine.category_id"=>14,"examine.check_status"=>["in",["0","1","2"]]])->sum("money");
            $money+=$param["money"];
            //先票后款可以不收款，先开票最多开订单总金额的票
            if($contract["crm_upqdbn"]=="先票后款"){
                if($money > $contract["money"]){
                    $this->error = '超过可开票金额';
                    return false;
                }
            }else{
                $moneyInfo = $receivablesModel->getMoneyByContractId($param["contract_ids"][0]);
                if($money>$moneyInfo["doneMoney"]){
                    $this->error = '超过可开票金额';
                    return false;
                }
            }
        }

        //报销判断
        if ($param["category_id"]==13){
            $receivables=Receivables::where(["receivables_id"=>$param["receivables_id"],"check_status"=>2])->find();
            if(empty($receivables)){
                $this->error = '该回款记录不存在或者未审核通过！';
                return false;
            }
            $contract_data=db("crm_contract")->where(["contract_id"=>$receivables["contract_id"]])->find();//合同订单
            if(empty($contract_data)){
                $this->error = '该合同订单不存在！';
                return false;
            }
            //该订单管家id、该合同的所属者
            /*if($param["create_user_id"] !=$contract_data["butler_id"] && $param["create_user_id"]!=$contract_data["create_user_id"]){
                $this->error = '对不起！您不是该订单所有者！';
                return false;
            }*/
            $refundOrder=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->find();//是否存在退款订单
            if($refundOrder){
                $this->error = "正在退款或已退款订单不能报销！";
                return false;
            }
            $expenseMoneySum=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额
            $max_expense_money=$receivables["crm_oeseng"]-$expenseMoneySum;//最大可报销金额=核定成本-待已报销金额
            if($param["money"] <= 0){
                $this->error = "报销金额必须大于0元！";
                return false;
            }
            if($param["money"] > $max_expense_money){
                $this->error = "报销金额不能超过{$max_expense_money}元！";
                return false;
            }
        }
        if ($param["category_id"]==15){
            //成本变更
            $contractModel = new Contract();
            $contract=$contractModel->find($param["contract_ids"][0]);
            if(empty($contract["butler_id"])){
                $this->error = '未捡取工单不能进行成本变更';
                return false;
            }
            if($contract["butler_id"]!=$param["create_user_id"]){
                $this->error = '只能变更自己捡取的工单';
                return false;
            }
            $contract_money=empty($contract)?0:$contract["crm_gvzubs"]+$contract["crm_vwvucv"]+$contract["crm_ahsoqz"];//+$contract["cost_production"];//办公件费用+返点费用+代收代付费用+工本费
            $receivablesModel = new \app\crm\model\Receivables();
            $moneyInfo = $receivablesModel->getMoneyByContractId($param["contract_ids"][0]);
            $calculate_money=$this->alias('examine')
                ->join('__OA_EXAMINE_RELATION__ examine_relation', 'examine_relation.examine_id = examine.examine_id', 'LEFT')
                ->where("examine_relation.contract_ids like '%,".$contract["contract_id"].",%'")
                ->whereIn("examine.check_status",[0,1])
                ->where(["examine.category_id"=>15,"crm_porzod"=>"增加"])->sum("money");
            $calculate_money2=$this->alias('examine')
                ->join('__OA_EXAMINE_RELATION__ examine_relation', 'examine_relation.examine_id = examine.examine_id', 'LEFT')
                ->where("examine_relation.contract_ids like '%,".$contract["contract_id"].",%'")
                ->whereIn("examine.check_status",[0,1])
                ->where(["examine.category_id"=>15,"crm_porzod"=>"减少"])->sum("money");
            $calculate_money-=$calculate_money2;
            if($param["crm_porzod"]=="增加"){
                $contract_money+=$param["money"];
                $contract_money+=$calculate_money;
            }
            if($contract_money>$moneyInfo["doneMoney"]){
                $this->error = '不可变更';
                return false;
            }
            if($param["crm_porzod"]=="减少"){
                $contract_money-=$param["money"];
                $contract_money-=$calculate_money;
                if($contract_money < 0){
                    $this->error = '不可变更';
                    return false;
                }
            }
            //如果回款金额大于核定成本---判断成本变更不能大于核定成本
            if($contract["crm_oeseng"]>$moneyInfo["doneMoney"]){
                //查找待审核已审核金额--核定成本变更
                $calculate_money=$this->alias('examine')
                    ->join('__OA_EXAMINE_RELATION__ examine_relation', 'examine_relation.examine_id = examine.examine_id', 'LEFT')
                    ->where("examine_relation.contract_ids like '%,".$contract["contract_id"].",%'")
                    ->whereIn("examine.check_status",[0,1])
                    ->where(["examine.category_id"=>17,"crm_porzod"=>"增加"])->sum("money");
                $calculate_money_cut=$this->alias('examine')
                    ->join('__OA_EXAMINE_RELATION__ examine_relation', 'examine_relation.examine_id = examine.examine_id', 'LEFT')
                    ->where("examine_relation.contract_ids like '%,".$contract["contract_id"].",%'")
                    ->whereIn("examine.check_status",[0,1])
                    ->where(["examine.category_id"=>17,"crm_porzod"=>"减少"])->sum("money");
                /*$calculate_money=bcsub($calculate_money,$calculate_money_cut,2);
                $calculate_money=bcadd($calculate_money,$contract["cost_production"]);//加上工本费*/
                $calculate_money=bcadd($contract["crm_oeseng"],(bcsub($calculate_money,$calculate_money_cut)));
                if($contract_money>$calculate_money){
                    $this->error = '不可变更';
                    return false;
                }
            }
        }
        //核定成本
        if ($param["category_id"]==17){
            //核定成本调整
            //2024-1-25 查找回款记录 start
            $receivables=Receivables::where(["receivables_id"=>$param["receivables_id"],"check_status"=>2])->find();
            if(empty($receivables)){
                $this->error = '该回款记录不存在或者未审核通过！';
                return false;
            }
            $oesengRecord=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"成本变更","check_status"=>["in",["0","1"]]])->find();//查询是否有未审核的核定成本变更记录
            if($oesengRecord){
                $this->error = '需要将在途变更订单先审批完成后再试！';
                return false;
            }
            $expenseMoney=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额

            if($param["money"] <= 0){
                $this->error = '变更金额不能为负';
                return false;
            }
            if($contract_money > $receivables["money"]){
                $this->error = '变更后核定成本不能超过回款金额';
                return false;
            }

            // 变更的成本
            $change_crm_oeseng = db("crm_finance")->where([
                "receivables_code"=>$receivables["number"],
                "order_type"=>"成本变更",
                "check_status"=>["in",[0,1,2]]
            ])->sum("crm_oeseng");
            // 退回业绩
            $calculate=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$receivables['number'],"check_status"=>["in",[0,1,2]]])->sum("calculate");
            if($param["crm_porzod"]=="减少"){
                // 最大可调减成本  = 核定成本
                // 核定成本 = 现有金额（回款单核定成本-成本调整增减成本）-退回成本（退款金额[仅“金额”，不含追回金额]-退回业绩）
                // 实际退款金额(不含追回金额)
                // 最大可调减成本  = 核定成本-报销金额
                $expenseMoneySum=db("crm_finance")->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额
                $should_refund_money=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$receivables['number'],"check_status"=>["in",[0,1,2]]])->sum("should_refund_money");
                // 退回成本 = 退款金额-退回业绩
                $th_crm_oeseng = bcadd($should_refund_money,$calculate,2);
                // 回款单核定成本+成本调整增减成本
                if($change_crm_oeseng > 0) {
                    $crm_oeseng = bcsub($receivables["crm_oeseng"],$change_crm_oeseng,2);
                } else {
                    $crm_oeseng = bcadd($receivables["crm_oeseng"],$change_crm_oeseng,2);
                }
                $max_down_oeseng = bcsub($crm_oeseng,$th_crm_oeseng,2);
                $max_down_oeseng = bcsub($max_down_oeseng,$expenseMoneySum,2);
                if( $max_down_oeseng < $param["money"] || $param["money"] < 0){
                    $this->error = "对不起！最大减少成本金额为{$max_down_oeseng}！";
                    return false;
                }
            }
            if($param["crm_porzod"]=="增加"){
                // 回款单业绩
                $refund_calculate = bcsub($receivables["money"],$receivables["crm_oeseng"],2);
                // 最大可调增成本 = 业绩金额
                // 业绩=现有金额（回款单核算业绩+成本调整增减业绩）-退回业绩（退款申请）
                $performance = bcsub($refund_calculate,$change_crm_oeseng,2);
                $max_up_oeseng = bcadd($performance,$calculate,2);
                if($max_up_oeseng < $param["money"] || $param["money"] < 0){
                    $this->error = "对不起！最大增加成本金额为{$max_up_oeseng}！";
                    return false;
                }
            }
        }
        //lina 新增 end
        // 自动验证
        $validateArr = $fieldModel->validateField($this->name,$param['category_id']); //获取自定义字段验证规则
        $validate = new Validate($validateArr['rule'], $validateArr['message']);            
        $result = $validate->check($param);
        if (!$result) {
            $this->error = $validate->getError();
            return false;
        }
        
        $categoryInfo = $examineCategoryModel->getDataById($param['category_id']);

        $fileArr = $param['file_id']; //接收表单附件
        unset($param['file_id']);
        if ($this->data($param)->allowField(true)->save()) {
            /*********************财务表添加数据************************/
            //$this->examine_id 审批表唯一标识
            if ($param["category_id"]==17){//核定成本变更
                $crm_oseng=$param["crm_porzod"]=="增加"?$param["money"]:-$param["money"];//核定成本金额
                $financeData=[
                    "create_user_id"=>$param['create_user_id'],//发起人
                    "customer_id"=>$receivables["customer_id"],//客户名称ID
                    "contract_id"=>$receivables["contract_id"],//订单编号ID
                    "receivables_code"=>$receivables["number"],//原回款的订单编号
                    "relation_id"=>$this->examine_id,//关联ID、type为2回款时关联receivables_id，2则examine_id
                    "department"=>Db::name("crm_contract")->where(["contract_id"=>$receivables["contract_id"]])->value("crm_kfhgfp"),//所属部门
                    "order_type"=>"成本变更",//订单类型（回款、退款、成本变更、报销）
                    "crm_oeseng"=>$crm_oseng,//核定成本金额
                    "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                    "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                    "calculate"=>bcsub(0,$crm_oseng,2),//业绩=回款-核定成本
                ];
                Db::name("crm_finance")->insert($financeData);
            }
            if($param["category_id"]==12 || $param['category_id']==30){//退款
                $financeData=[
                    "create_user_id"=>$param['create_user_id'],//发起人
                    "customer_id"=>$receivables["customer_id"],//客户名称ID
                    "contract_id"=>$receivables["contract_id"],//订单编号ID
                    "receivables_code"=>$receivables["number"],//原回款的订单编号
                    "relation_id"=>$this->examine_id,//关联ID、type为2回款时关联receivables_id，2则examine_id
                    "department"=>Db::name("crm_contract")->where(["contract_id"=>$receivables["contract_id"]])->value("crm_kfhgfp"),//所属部门
                    "order_type"=>"退款",//订单类型（回款、退款、成本变更、报销）
                    "recover_money"=>$param["recover_money"],//追回成本
                    "refund_money"=>$param["money"],//退款金额
                    "should_refund_money"=>bcsub($param["money"],$param["recover_money"],2),//应退款金额
                    "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                    "calculate_way"=>$param["crm_upqdbn"],//业绩处理方式，只针对回款和退款(正常核算、暂不核算、业绩抵扣、提成退回)',
                    "calculate"=>bcsub(0,$param["calculate"],2),//业绩
                    "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                ];
                Db::name("crm_finance")->insert($financeData);
            }
            if($param["category_id"]==13){//报销
                $financeData=[
                    "create_user_id"=>$param['create_user_id'],//发起人
                    "customer_id"=>$receivables["customer_id"],//客户名称ID
                    "contract_id"=>$receivables["contract_id"],//订单编号ID
                    "receivables_code"=>$receivables["number"],//原回款的订单编号
                    "relation_id"=>$this->examine_id,//关联ID、type为2回款时关联receivables_id，2则examine_id
                    "department"=>Db::name("crm_contract")->where(["contract_id"=>$receivables["contract_id"]])->value("crm_kfhgfp"),//所属部门
                    "order_type"=>"报销",//订单类型（回款、退款、成本变更、报销）
                    "reimburse_money"=>$param["money"],//报销金额
                    "expense_type"=>$param["expense_type"],//报销类型
                    "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                    "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                ];
                Db::name("crm_finance")->insert($financeData);
            }
            /*********************财务表添加数据************************/
            //处理自定义字段数据
            $resData = $examineDataModel->createData($param, $this->examine_id);
            if ($resData) {
                //处理附件关系
                if ($fileArr) {
                    $fileModel = new \app\admin\model\File();
                    $resData = $fileModel->createDataById($fileArr, 'oa_examine', $this->examine_id);
                    if ($resData == false) {
                        $this->error = '附件上传失败';
                        return false;
                    }
                }
                //相关业务
                $rdata = [];
                $rdata['customer_ids'] = $param['customer_ids'] ? arrayToString($param['customer_ids']) : '';
                $rdata['contacts_ids'] = $param['contacts_ids'] ? arrayToString($param['contacts_ids']) : '';
                $rdata['business_ids'] = $param['business_ids'] ? arrayToString($param['business_ids']) : '';
                $rdata['contract_ids'] = $param['contract_ids'] ? arrayToString($param['contract_ids']) : '';
                $rdata['examine_id'] = $this->examine_id;
                $rdata['status'] = 1;
                $rdata['create_time'] = time();             
                Db::name('OaExamineRelation')->insert($rdata);                              

                //处理差旅相关
                $resTravel = true;
                if (in_array($param['category_id'],['3','5']) && $param['cause']) {
                    $resTravel = $this->createTravelById($param['cause'], $this->examine_id);
                }
                if (!$resTravel) {
                    $this->error = '相关事项保存失败，请重试';
                    return false;
                }
                //站内信
                $createUserInfo = $userModel->getDataById($param['create_user_id']);
                $send_user_id = stringToArray($param['check_user_id']);
                $sendContent = $createUserInfo['realname'].'提交的【'.$categoryInfo['title'].'】,需要您审批';
                if ($send_user_id) {
                    sendMessage($send_user_id, $sendContent, $this->examine_id, 1);
                }            

                $data = [];
                $data['examine_id'] = $this->examine_id;

                return $data;               
            } else {
                $this->error = $examineDataModel->getError();
                return false;               
            }
        } else {
            $this->error = '添加失败';
            return false;
        }           
    }

    /**
     * 编辑审批信息
     * @author Michael_xu
     * @param  
     * @return                            
     */ 
    public function updateDataById($param, $examine_id = '')
    {
        $examine_id = intval($examine_id);
        $userModel = new \app\admin\model\User();
        $examineCategoryModel = new \app\oa\model\ExamineCategory();
        unset($param['id']);
        $dataInfo = db('oa_examine')->where(['examine_id' => $examine_id])->find();
        if (!$dataInfo) {
            $this->error = '数据不存在或已删除';
            return false;
        }
        //过滤不能修改的字段
        $unUpdateField = ['create_user_id','is_deleted','delete_time'];
        foreach ($unUpdateField as $v) {
            unset($param[$v]);
        }
        $categoryInfo = $examineCategoryModel->getDataById($dataInfo['category_id']);
        
        //验证
        $fieldModel = new \app\admin\model\Field();
        $validateArr = $fieldModel->validateField($this->name, $dataInfo['category_id']); //获取自定义字段验证规则
        $validate = new Validate($validateArr['rule'], $validateArr['message']);
        $result = $validate->check($param);
        if (!$result) {
            $this->error = $validate->getError();
            return false;
        }
        
        $fileArr = $param['file_id']; //接收表单附件
        unset($param['file_id']);
    
        if ($this->allowField(true)->save($param, ['examine_id' => $examine_id])) {
            if($param['category_id'] == 17) {
                db("oa_examine_data")->where('examine_id',$examine_id)->where('field','crm_porzod')->update([
                    'value' => $param['crm_porzod']    
                ]);
            }

            if($param['category_id']==12){
                if($param["money"] <= 0 && $param["recover_money"]<=0){
                    $this->error = "退款金额和追会成本不能同时为0元";
                    return false;
                }
                $receivables=Receivables::where(["number"=>$param["receivables_id"],"check_status"=>2])->find();
                if(empty($receivables)){
                    $this->error = '该回款记录不存在或者未审核通过！';
                    return false;
                }
                $recoverMoney=db("crm_finance")->where('relation_id','<>',$examine_id)->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->sum("recover_money");//已经追回的成本
                $refundMoney=db("crm_finance")->where('relation_id','<>',$examine_id)->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款","check_status"=>["in",[0,1,2]]])->sum("refund_money");//已退款和正在等待审核的退款金额
                $expenseMoneySum=db("crm_finance")->where('relation_id','<>',$examine_id)->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("money");//待已报销金额
                $expenseMoney=db("crm_finance")->where('relation_id','<>',$examine_id)->where(["receivables_code"=>$receivables["number"],"order_type"=>"报销","check_status"=>2])->sum("money");//已报销金额
                $max_recover_money=bcsub($expenseMoney,$recoverMoney,2);//最大可追回的报销金额
                $max_refund_money=bcsub($receivables["money"],bcadd($refundMoney,$expenseMoneySum),2);//最大该回款单可退款金额
                if($param["recover_money"] > $max_recover_money){
                    $this->error = "追回金额不能超过{$max_recover_money}元！";
                    return false;
                }
                if($param["calculate"] > $param["money"]){
                    $this->error = "业绩处理金额不能超过{$param["money"]}元！";
                    return false;
                }
                if($param["money"] > $max_refund_money){
                    $this->error = "退款金额不能超过{$max_refund_money}元！";
                    return false;
                }
                $param["money"]=bcadd($param["money"],$param["recover_money"],2);//合并退款金额=退款金额+追回金额
                
                // 编辑
                db("crm_finance")->where('relation_id',$examine_id)->where(["receivables_code"=>$receivables["number"],"order_type"=>"退款"])->update([
                    "refund_money" => $param["money"],
                    "check_status" => 0,
                    "recover_money"=>$param["recover_money"],
                    "should_refund_money"=>bcsub($param["money"],$param["recover_money"],2),//应退款金额
                    "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                    "calculate_way"=>$param["crm_upqdbn"],//业绩处理方式，只针对回款和退款(正常核算、暂不核算、业绩抵扣、提成退回)',
                    "calculate"=>bcsub(0,$param["calculate"],2),//业绩
                    "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                ]);
                $fieldList = db('admin_field')->where(['types' => 'oa_examine','types_id' => $param['category_id']])->select();
                //过滤掉固定字段
                $unField = ['receivables_id','content','remark','start_time','end_time','duration','cause','money','category_id','check_user_id','check_status','flow_id','order_id','create_user_id'];
                foreach ($fieldList as $key => $value) {
                    if(isset($param[$value['field']]) && !in_array($value['field'], $unField)) {
                        db("oa_examine_data")->where(['examine_id'=>$examine_id,'field'=>$value['field']])->update([
                            'value' => $param[$value['field']]
                        ]);
                    }
                }
                
            }

            //处理附件关系
            if ($fileArr) {
                $fileModel = new \app\admin\model\File();
                $resData = $fileModel->createDataById($fileArr, 'oa_examine', $examine_id);
                if ($resData == false) {
                    $this->error = '附件上传失败';
                    return false;
                }
            }           

            //站内信
            $createUserInfo = $userModel->getDataById($param['user_id']);
            $send_user_id = stringToArray($param['check_user_id']);
            $sendContent = $createUserInfo['realname'].'提交了【'.$categoryInfo['title'].'】,需要您审批';
            if ($send_user_id) {
                sendMessage($send_user_id, $sendContent, $examine_id, 1);
            }

            //相关业务
            $rdata = [];
            $rdata['customer_ids'] = $param['customer_ids'] ? arrayToString($param['customer_ids']) : [];
            $rdata['contacts_ids'] = $param['contacts_ids'] ? arrayToString($param['contacts_ids']) : [];
            $rdata['business_ids'] = $param['business_ids'] ? arrayToString($param['business_ids']) : [];
            $rdata['contract_ids'] = $param['contract_ids'] ? arrayToString($param['contract_ids']) : [];       
            Db::name('OaExamineRelation')->where('examine_id = '.$examine_id)->update($rdata);  

            //处理差旅相关
            $resTravel = true;
            if (in_array($dataInfo['category_id'],['3','5']) && $param['cause']) {
                $resTravel = $this->updateTravelById($param['cause'], $examine_id);
            }
            if (!$resTravel) {
                $this->error = '相关事项保存失败，请重试';
                return false;
            }
            //站内信
            $createUserInfo = $userModel->getDataById($dataInfo['create_user_id']);
            $send_user_id = stringToArray($param['check_user_id']);
            $sendContent = $createUserInfo['realname'].'提交的【'.$categoryInfo['title'].'】,需要您审批';
            if ($send_user_id) {
                sendMessage($send_user_id, $sendContent, $examine_id, 1);
            }                               

            $data = [];
            $data['examine_id'] = $examine_id;
            return $data;
        } else {
            $this->error = '编辑失败';
            return false;
        }                   
    }

    /**
     * 审批数据
     * @param  $id 审批ID
     * @return 
     */ 
    public function getDataById($id = '')
    {   
        $examineData = new \app\oa\model\ExamineData();
        $fieldModel = new \app\admin\model\Field();     
        $fileModel = new \app\admin\model\File();       
        $map['examine.examine_id'] = $id;
        $data_view = db('oa_examine')
                     ->where($map)
                     ->alias('examine')
                     ->join('__OA_EXAMINE_CATEGORY__ examine_category', 'examine_category.category_id = examine.category_id', 'LEFT');

        $dataInfo = $data_view
                    ->field('examine.*,examine_category.title as category_name')
                    ->find();
        if (!$dataInfo) {
            $this->error = '暂无此数据';
            return false;
        }
        //自定义字段信息
        $examineDataInfo = $examineData->getDataById($id);
        if($examineDataInfo && $examineDataInfo["receivables_id"]){
            $examineDataInfo["receivables_id"]=db("crm_receivables")->where(["receivables_id"=>$examineDataInfo["receivables_id"]])->value("number");
        }
        //crm_abrykp 收款人 expense_type 报销类型 crm_fgkvvb 开户行 crm_wsxyed 银行账号
        $expence=Db::name("crm_expence")->where(["examine_id"=>$id])->field("id expence_id,payee crm_abrykp,opening_bank crm_fgkvvb,bank_number crm_wsxyed")->find();
        if($expence){
            $expence["expense_type"]="请在详情中查看";
            $examineDataInfo["receivables_id"]="批量报销";
            $examineDataInfo=array_merge($examineDataInfo,$expence);
        }
        //批量开票专用
        $invoice=Db::name("crm_invoice")->where(["examine_id"=>$id])->field("id invoice_id")->find();
        if($invoice){
            $examineDataInfo=array_merge($examineDataInfo,$invoice);
        }
        $dataInfo = $examineDataInfo ? array_merge($dataInfo,$examineDataInfo) : $dataInfo;

        //表格数据处理
        // $fieldList = $fieldModel->getFieldByFormType('oa_examine', 'form');
        // foreach ($fieldList as $k=>$v) {
        //  $dataInfo[$v] = $fieldModel->getFormValueByField($v, $dataInfo[$v]);
        // }

        //关联业务
        $businessModel = new \app\crm\model\Business();
        $contactsModel = new \app\crm\model\Contacts();
        $contractModel = new \app\crm\model\Contract();
        $customerModel = new \app\crm\model\Customer();
        $relation = Db::name('OaExamineRelation')->where('examine_id ='.$id)->find();
        $dataInfo['businessList'] = $relation['business_ids'] ? $businessModel->getDataByStr($relation['business_ids']) : []; //商机
        $dataInfo['contactsList'] = $relation['contacts_ids'] ? $contactsModel->getDataByStr($relation['contacts_ids']) : []; //联系人
        $dataInfo['contractList'] = $relation['contract_ids'] ? $contractModel->getDataByStr($relation['contract_ids']) : []; //合同
        $dataInfo['customerList'] = $relation['customer_ids'] ? $customerModel->getDataByStr($relation['customer_ids']) : []; //客户  

        $travelList = [];
        if (in_array($dataInfo['category_id'],['3','5'])) {
            //行程、费用明细
            $whereTravel = [];
            $whereTravel['examine_id'] = $dataInfo['examine_id'];
            $travelList = db('oa_examine_travel')->where($whereTravel)->select() ? : [];
            foreach ($travelList as $k=>$v) {
                //附件
                $fileList = [];
                $imgList = [];
                $where = [];
                $where['module'] = 'oa_examine_travel';
                $where['module_id'] = $v['travel_id'];          
                $newFileList = [];
                $newFileList = $fileModel->getDataList($where, 'all');
                if ($newFileList['list']) {
                    foreach ($newFileList['list'] as $val) {
                        if ($val['types'] == 'file') {
                            $fileList[] = $val;
                        } else {
                            $imgList[] = $val;
                        }
                    }                   
                }               
                $travelList[$k]['fileList'] = $fileList ? : [];
                $travelList[$k]['imgList'] = $imgList ? : [];               
            }           
        }
        $dataInfo['travelList'] = $travelList;

        //附件
        $fileList = [];
        $imgList = [];
        $where = [];
        $where['module'] = 'oa_examine';
        $where['module_id'] = $id;          
        $newFileList = [];
        $newFileList = $fileModel->getDataList($where, 'all');
        foreach ($newFileList['list'] as $val) {
            if ($val['types'] == 'file') {
                $fileList[] = $val;
            } else {
                $imgList[] = $val;
            }
        }
        $dataInfo['fileList'] = $fileList ? : [];
        $dataInfo['imgList'] = $imgList ? : [];                

        $userModel = new \app\admin\model\User();
        $dataInfo['create_user_info'] = $userModel->getUserById($dataInfo['create_user_id']);
        $dataInfo['examine_id'] = $id;
        return $dataInfo;
    }

    /**
     * 审批差旅数据保存
     * @param  examine_id 审批ID
     * @return 
     */
    public function createTravelById($data = [], $examine_id)
    {
        if (!$examine_id) {
            $this->error = '参数错误';
            return false;
        }
        $successRes = true;
        foreach ($data as $k=>$v) {
            $newData = [];
            $fileArr = [];
            unset($v['files']);
            $newData = $v;
            $newData['examine_id'] = $examine_id;
            $fileArr = $v['file_id']; //接收表单附件
            unset($newData['file_id']);
            unset($newData['fileList']);
            unset($newData['fileList']);            
            if ($travel_id = db('oa_examine_travel')->insertGetId($newData)) {
                //处理附件关系
                if ($fileArr) {
                    $fileModel = new \app\admin\model\File();
                    $resData = $fileModel->createDataById($fileArr, 'oa_examine_travel', $travel_id);
                    if ($resData == false) {
                        $successRes = false;
                        return false;
                    }
                }
            } else {
                $successRes = false;
                return false;
            }               
        }
        if (!$successRes) {
            $this->error = '审批事项创建失败';
            return false;
        }
        return true;                
    } 

    /**
     * 审批差旅数据编辑
     * @param  examine_id 审批ID
     * @return 
     */
    public function updateTravelById($data = [], $examine_id)
    {
        if (!$examine_id) {
            $this->error = '参数错误';
            return false;
        }
        $oldTravelIds = db('oa_examine_travel')->where(['examine_id' => $examine_id])->column('travel_id');
        $oldTravelFileIds = db('oa_examine_travel_file')->where(['travel_id' => ['in',$oldTravelIds]])->column('r_id');

        $successRes = true;
        foreach ($data as $k=>$v) {
            $newData = [];
            $fileArr = [];
            unset($v['files']);
            $newData = $v;
            $newData['examine_id'] = $examine_id;
            $fileArr = $v['file_id']; //接收表单附件
            unset($newData['file_id']);
            unset($newData['fileList']);
            unset($newData['imgList']);
            unset($newData['travel_id']);
            if ($travel_id = db('oa_examine_travel')->insertGetId($newData)) {
                //处理附件关系
                if ($fileArr) {
                    $fileModel = new \app\admin\model\File();
                    $resData = $fileModel->createDataById($fileArr, 'oa_examine_travel', $travel_id);
                    if ($resData == false) {
                        $successRes = false;
                        return false;
                    }
                }
            } else {
                $successRes = false;
                return false;
            }               
        }
        if (!$successRes) {
            $this->error = '审批事项创建失败';
            return false;
        }
        //删除旧数据
        if ($oldTravelIds) db('oa_examine_travel')->where(['travel_id' => ['in',$oldTravelIds]])->delete();
        if ($oldTravelFileIds) db('oa_examine_travel_file')->where(['r_id' => ['in',$oldTravelFileIds]])->delete();     
        return true;                
    }    
}